home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / human interface toolbox / live scroll / scrollbars.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  6.1 KB  |  293 lines

  1. /*
  2.     File:        ScrollBars.c
  3.  
  4.     Contains:    List Manager stuff and associated routines
  5.  
  6.     Written by: Chris White    
  7.  
  8.     Copyright:    Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 8/6/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 
  21.  
  22. */
  23.  
  24.  
  25. #pragma segment Core
  26.  
  27.  
  28. // System Includes
  29.  
  30.  
  31.  
  32. // Application Includes
  33.  
  34. #ifndef __BAREBONES__
  35.     #include "BareBones.h"
  36. #endif
  37.  
  38.  
  39. #ifndef __PROTOTYPES__
  40.     #include "Prototypes.h"
  41. #endif
  42.  
  43.  
  44.  
  45.  
  46.  
  47. static ControlRef   gControl;
  48. static SInt32        gValueSlop;
  49. static SInt32        gSaveValue;
  50. static SInt32        gStartValue;
  51. static RgnHandle    gSaveClip = nil;
  52.  
  53.  
  54.  
  55. static SInt32    CalcValueFromPoint ( ControlRef theControl, Point thePoint );
  56. static void        DisableDrawing ( void );
  57. static void        EnableDrawing ( void );
  58.  
  59.  
  60.  
  61.  
  62.  
  63. OSErr BeginThumbTracking ( ControlRef theControl )
  64. {
  65.     const SInt32 kMinLowMem    = 512;
  66.     
  67.     OSErr    theErr = noErr;
  68.     Size    theGrow;
  69.     Point    thePoint;
  70.     
  71.     gControl = theControl;
  72.     gStartValue = GetControlValue ( theControl );
  73.     
  74.     gValueSlop = 0;
  75.     GetMouse ( &thePoint );
  76.     gValueSlop = GetControlValue ( theControl ) - CalcValueFromPoint ( theControl, thePoint );    
  77.     
  78.     // Preflight memory for call to NewRgn
  79.     if ( MaxMem ( &theGrow ) < kMinLowMem )
  80.     {
  81.         theErr = memFullErr;
  82.         goto CleanupAndBail;
  83.     }
  84.     gSaveClip = NewRgn ( );
  85.     
  86.     DisableDrawing ( );
  87.     
  88. CleanupAndBail:
  89.     // Don't have to do any cleanup here
  90.     
  91.     return theErr;
  92. }
  93.  
  94.     
  95.  
  96. void EndThumbTracking ( void )
  97. {
  98.     EnableDrawing ( );
  99.     
  100.     DisposeRgn ( gSaveClip );
  101.     SetControlValue ( gControl, gSaveValue );
  102.     
  103.     return;
  104. }
  105.  
  106.  
  107.  
  108. pascal void ScrollThumbActionProc ( void )
  109. {
  110.     SInt32            theValue;
  111.     WindowRef        theWindow;
  112.     ControlRef        theControl = gControl;
  113.     Point            thePoint;
  114.     Rect            theRect;
  115.     tWindowInfoPtr    theInfo;
  116.     
  117.     
  118.     theWindow = (*theControl)->contrlOwner;
  119.     theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
  120.     
  121.     #if DEBUGGING
  122.     if ( theInfo == nil ) DebugStr ( "\p theInfo == nil" );
  123.     #endif
  124.     
  125.      theRect = (*theControl)->contrlRect;
  126.      if ( theControl == theInfo->hScrollBar )
  127.         InsetRect ( &theRect, -kThumbTrackLengthSlop, -kThumbTrackWidthSlop );
  128.      else
  129.         InsetRect ( &theRect, -kThumbTrackWidthSlop, -kThumbTrackLengthSlop );
  130.     
  131.     // Assumes the port is correctly set up
  132.     GetMouse ( &thePoint );
  133.     if ( PtInRect ( thePoint, &theRect ) )
  134.         theValue = CalcValueFromPoint ( theControl, thePoint );
  135.     else
  136.         theValue = gStartValue;
  137.     
  138.     if ( theValue != GetControlValue ( theControl ) )
  139.     {
  140.         EnableDrawing ( );
  141.         
  142.         gSaveValue = theValue;
  143.          SetControlValue ( theControl, theValue );
  144.          UpdateWindowContent ( theWindow );
  145.          
  146.          DisableDrawing ( );
  147.          
  148.     }
  149.     
  150.     return;
  151. }
  152.  
  153.  
  154.  
  155. pascal void ScrollControlActionProc ( ControlRef theControl, SInt16 thePart )
  156. {
  157.     WindowRef        theWindow;
  158.     tWindowInfoPtr    theInfo;
  159.     SInt32            theValue,
  160.                     theDistance,
  161.                     limitValue;
  162.     
  163.     
  164.     theWindow = (*theControl)->contrlOwner;
  165.     theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
  166.     
  167.     #if DEBUGGING
  168.     if ( theInfo == nil ) DebugStr ( "\p theInfo == nil" );
  169.     #endif
  170.     
  171.     
  172.     switch ( thePart )
  173.     {
  174.         case kControlUpButtonPart:
  175.         case kControlDownButtonPart:
  176.             theDistance = 10;
  177.         break;
  178.             
  179.         case kControlPageUpPart:
  180.         case kControlPageDownPart:
  181.             if ( theControl == theInfo->hScrollBar )
  182.                 theDistance = (theWindow->portRect.right - theWindow->portRect.left)
  183.                                                 - kScrollBarWidth - kPageOverlap;
  184.             else
  185.                 theDistance = (theWindow->portRect.bottom - theWindow->portRect.top)
  186.                                                 - kScrollBarWidth - kPageOverlap;
  187.         break;
  188.     }
  189.     
  190.     theValue = GetControlValue ( theControl );
  191.     
  192.     switch ( thePart )
  193.     {
  194.         case kControlUpButtonPart:
  195.         case kControlPageUpPart:
  196.             limitValue = GetControlMinimum ( theControl );
  197.             if ( theValue - theDistance < limitValue )
  198.                 theValue = limitValue;
  199.             else
  200.                 theValue -= theDistance;
  201.         break;
  202.                 
  203.         case kControlDownButtonPart:
  204.         case kControlPageDownPart:
  205.             limitValue = GetControlMaximum ( theControl );
  206.             if ( theValue + theDistance > limitValue )
  207.                 theValue = limitValue;
  208.             else
  209.                 theValue += theDistance;
  210.         break;
  211.     }
  212.     
  213.     SetControlValue ( theControl, theValue );
  214.     UpdateWindowContent ( theWindow );
  215.     
  216.     return;
  217. }
  218.  
  219.  
  220.  
  221. static SInt32 CalcValueFromPoint ( ControlRef theControl, Point thePoint )
  222. {
  223.     SInt32            theValue,
  224.                     theRange,
  225.                     theDistance,
  226.                     thePin;
  227.     Rect            theRect;
  228.     WindowRef        theWindow;
  229.     tWindowInfoPtr    theInfo;
  230.     
  231.     
  232.     theWindow = (*theControl)->contrlOwner;
  233.     theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
  234.     
  235.     #if DEBUGGING
  236.     if ( theInfo == nil ) DebugStr ( "\p theInfo == nil" );
  237.     #endif
  238.         
  239.     theRect = (*theControl)->contrlRect;
  240.     theRange = GetControlMaximum ( theControl ) - GetControlMinimum ( theControl );
  241.     if ( theControl == theInfo->vScrollBar )
  242.     {
  243.         // Scroll distance adjusted for scroll arrows and the thumb
  244.         theDistance = theRect.bottom - theRect.top - kTotalWidthAdjust;
  245.         
  246.         // Pin thePoint to the middle of the thumb
  247.         thePin = theRect.top + (kTotalWidthAdjust / 2);
  248.         
  249.         theValue = ((thePoint.v - thePin) * theRange) / theDistance;
  250.     }
  251.     else
  252.     {
  253.         // Scroll distance adjusted for scroll arrows and the thumb
  254.         theDistance = theRect.right - theRect.left - kTotalWidthAdjust;
  255.         
  256.         // Pin thePoint to the middle of the thumb
  257.         thePin = theRect.left + (kTotalWidthAdjust / 2);
  258.         
  259.         theValue = ((thePoint.h - thePin) * theRange) / theDistance;
  260.     }
  261.     
  262.     theValue += gValueSlop;
  263.     
  264.     
  265.     if ( theValue < GetControlMinimum ( theControl ) )
  266.         theValue = GetControlMinimum ( theControl );
  267.     else if ( theValue > GetControlMaximum ( theControl ) )
  268.         theValue = GetControlMaximum ( theControl );
  269.     
  270.     return theValue;
  271. }
  272.  
  273.  
  274.  
  275. static void DisableDrawing ( void )
  276. {
  277.      Rect    nullRect = { 0, 0, 0, 0 };
  278.  
  279.     GetClip ( gSaveClip );
  280.     ClipRect ( &nullRect );
  281.     
  282.     return;
  283. }
  284.  
  285.  
  286.  
  287. static void EnableDrawing ( void )
  288. {
  289.     SetClip ( gSaveClip );
  290.     
  291.     return;
  292. }
  293.